#property copyright   "Copyright 2012,"
#property link "mxhe2001@hotmail.com"

#define LONG          1
#define SHORT         0
#define ALL           2
#define RETRYCOUNT    10
#define RETRYDELAY    500

extern string TimeFrame_Help = "0 = Current TF, 1=M1, 5=M5, 15=M15, ..., 1440=D1, 10080=W1, 43200=MN1";
extern int    TimeFrame = 30;

extern string Oscillator_Setting  = "------Oscillator Setting-------";
extern int    K_Period        = 5;      //K% Period
extern int    D_Period        = 3;      //D% Period
extern int    Slowing         = 3;      //Slowing
extern string MA.Method.Desc = "0-MODE_SMA;1-MODE_EMA;2-MODE_SMMA;3-MODE_LWMA";
extern int    MA.Method=0;
extern string Price.Field.Desc = "0-Low/High;1-Close/Close";
extern int    Price.Field = 0;
extern double BuyLot1Limit = 20;
extern double BuyLot2Limit = 10;
extern double SellLot1Limit = 80;
extern double SellLot2Limit = 90;

extern string Turtle_Setting  = "------Turtle Setting-------";
extern string Turtle_IndicatorName = "TheTurtleTradingChannel";
extern bool   UseTurtleTrend      = false;
extern int    TradePeriod         = 20;     // Donchian channel period for trading signals
extern int    StopPeriod          = 10;     // Donchian channel period for exit signals
extern bool   Strict              = false;  // Apply strict entry parameters like the Turtles did
extern int    TurtleShift         = 0;
extern double MaxDistanceToTurtle.Pips    = 20;

extern string RSI_Setting  = "------RSI Setting-------";
extern bool   UseRSI          = true;
extern int    RSI_Period      = 14;      //RSI Period - Put below or equl 1 for 1 direction trading, LONG only
extern string RSI.Applied.Price.Desc = "0:PRICE_CLOSE;1:PRICE_OPEN;2:PRICE_HIGH;3:PRICE_LOW";
extern int    RSI.Applied.Price = 0;
extern double RSI.Over_sold = 50;
extern double RSI.Over_bought = 50;

extern string TrailingStop_Setting  = "------TrailingStop Setting-------";
extern bool   UseTrailingStop = true;
extern double TrailingStopActive.Pips = 30;
extern double TrailingStopStep.Pips = 1;
extern double TrailingStopLoss.Pips = 5;

extern string StopLoss_Setting  = "------StopLoss Setting-------";
extern bool   UseFixedStopLoss = true;
extern double Fixed.StopLoss.Pips = 50;
extern bool   UseTurtleStopLoss = true;
extern double Turtle.StopLoss.Pips = 60;

extern string MoneyManagement_Setting  = "------MoneyManagement Setting-------";
extern double MaxDrawdownPercent = 100;
extern double Risk.Percent.Of.Balance = 0;
extern double Lotsize1 = 0.1;
extern double Lotsize2 = 0.2;

extern string Close_Setting  = "------Close Setting-------";
extern bool   UseTacticClosingStrategy = true;
extern double HighLevelForBuy = 80;
extern double LowLevelForSell = 20;

extern string Other_Setting  = "------Other Setting-------";
extern int    MagicNumber=20111219;
extern int    Slippage = 3;

int digitFactor = 1;
int orders.total, orders.BUY, orders.SELL, orders.BUYLIMIT, orders.BUYSTOP, orders.SELLLIMIT, orders.SELLSTOP;
datetime lastActTime;
bool stopEA;

void init()
{   
    if(Bid<10 && Digits==5) { digitFactor=10;}
    if(Bid<10 && Digits==4) { digitFactor= 1;}

    if(Bid>10 && Digits==3) { digitFactor=10;}
    if(Bid>10 && Digits==2) { digitFactor= 1;}   
        
    MaxDistanceToTurtle.Pips *= digitFactor; 
    TrailingStopActive.Pips *= digitFactor;    
    TrailingStopStep.Pips *= digitFactor;    
    TrailingStopLoss.Pips *= digitFactor;
    Turtle.StopLoss.Pips *= digitFactor;
    Fixed.StopLoss.Pips *= digitFactor;
}

void deinit()
{
    switch( UninitializeReason() ) {
    case REASON_REMOVE:
    case REASON_ACCOUNT:   
      break;
   }
}

void start()
{
    if (stopEA)
    {
        return;
    }
    
    double stoMainPre = iStochastic(NULL,TimeFrame,K_Period,D_Period,Slowing,MA.Method,Price.Field,MODE_MAIN, 2);
    double stoMainCur = iStochastic(NULL,TimeFrame,K_Period,D_Period,Slowing,MA.Method,Price.Field,MODE_MAIN, 1);
    double stoMainNow = iStochastic(NULL,TimeFrame,K_Period,D_Period,Slowing,MA.Method,Price.Field,MODE_MAIN, 0);
    
    double bottomTurtle = iCustom(NULL,TimeFrame,Turtle_IndicatorName,TradePeriod,StopPeriod,Strict, 0, TurtleShift);
    double topTurtle = iCustom(NULL,TimeFrame,Turtle_IndicatorName,TradePeriod,StopPeriod,Strict, 1, TurtleShift);
    
    double myrsi=iRSI(NULL,TimeFrame,RSI_Period,RSI.Applied.Price,0);
        
    if (iTime(Symbol(),TimeFrame,0) > lastActTime)
    {
         if (stoMainPre >= BuyLot1Limit && stoMainCur < BuyLot1Limit && 
             (!UseRSI || myrsi <= RSI.Over_sold) && 
             (!UseTurtleTrend || (bottomTurtle > 0 && bottomTurtle != EMPTY_VALUE && Ask - bottomTurtle <= MaxDistanceToTurtle.Pips*Point)))
         {             
             if (DoOpenOrder(Symbol(), LONG, getLots(Symbol(), Lotsize1), 0, 0, Blue, "FORTA3") > 0)
             {
                 if (UseTurtleTrend)
                 {
                     if (UseTurtleStopLoss)
                     {
                         double stopLoss = bottomTurtle - Turtle.StopLoss.Pips*Point;
                         modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), stopLoss, OrderTakeProfit());
                     }
                 }
                 else 
                 {
                     if (UseFixedStopLoss)
                     {
                         stopLoss = OrderOpenPrice() - Fixed.StopLoss.Pips*Point;
                         modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), stopLoss, OrderTakeProfit());
                     }
                 }                                      
                
                 lastActTime = iTime(Symbol(),TimeFrame,0);
             }
         }
         
         if (stoMainPre >= BuyLot2Limit && stoMainCur < BuyLot2Limit && 
             (!UseRSI || myrsi <= RSI.Over_sold) &&
             (!UseTurtleTrend || (bottomTurtle > 0 && bottomTurtle != EMPTY_VALUE && Ask - bottomTurtle <= MaxDistanceToTurtle.Pips*Point)))
         {             
             if (DoOpenOrder(Symbol(), LONG, getLots(Symbol(), Lotsize2), 0, 0, Blue, "FORTA3") > 0)
             {
                 if (UseTurtleTrend)
                 {
                     if (UseTurtleStopLoss)
                     {
                         stopLoss = bottomTurtle - Turtle.StopLoss.Pips*Point;
                         modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), stopLoss, OrderTakeProfit());
                     }
                 }
                 else 
                 {
                     if (UseFixedStopLoss)
                     {
                         stopLoss = OrderOpenPrice() - Fixed.StopLoss.Pips*Point;
                         modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), stopLoss, OrderTakeProfit());
                     }
                 }          
                 lastActTime = iTime(Symbol(),TimeFrame,0);
             }
         }
         
         if (stoMainPre <= SellLot1Limit && stoMainCur > SellLot1Limit && 
             (!UseRSI || myrsi>= RSI.Over_bought) &&
              (!UseTurtleTrend || (topTurtle > 0 && topTurtle != EMPTY_VALUE && topTurtle - Bid <= MaxDistanceToTurtle.Pips*Point)))
         {                          
             if (DoOpenOrder(Symbol(), SHORT, getLots(Symbol(), Lotsize1), 0, 0, Red, "FORTA3") > 0)
             {
                 if (UseTurtleTrend)
                 {
                     if (UseTurtleStopLoss)
                     {
                         stopLoss = topTurtle + Turtle.StopLoss.Pips*Point;
                         modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), stopLoss, OrderTakeProfit());
                     }
                 }
                 else 
                 {
                     if (UseFixedStopLoss)
                     {
                         stopLoss = OrderOpenPrice() + Fixed.StopLoss.Pips*Point;
                         modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), stopLoss, OrderTakeProfit());
                     }
                 }          
                 
                 lastActTime = iTime(Symbol(),TimeFrame,0);
             }
         }
         
         if (stoMainPre <= SellLot2Limit && stoMainCur > SellLot2Limit && 
             (!UseRSI || myrsi >= RSI.Over_bought) &&
             (!UseTurtleTrend || (topTurtle > 0 && topTurtle != EMPTY_VALUE && topTurtle - Bid <= MaxDistanceToTurtle.Pips*Point)))
         {                          
             if (DoOpenOrder(Symbol(), SHORT, getLots(Symbol(), Lotsize2), 0, 0, Red, "FORTA3") > 0)
             {
                 if (UseTurtleTrend)
                 {
                     if (UseTurtleStopLoss)
                     {
                         stopLoss = topTurtle + Turtle.StopLoss.Pips*Point;
                         modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), stopLoss, OrderTakeProfit());
                     }
                 }
                 else 
                 {
                     if (UseFixedStopLoss)
                     {
                         stopLoss = OrderOpenPrice() + Fixed.StopLoss.Pips*Point;
                         modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), stopLoss, OrderTakeProfit());
                     }
                 }  
                 
                 lastActTime = iTime(Symbol(),TimeFrame,0);
             }
         }
    }
    
    CountOrders(Symbol());
    
    if (orders.total > 0 && UseTacticClosingStrategy)
    {         
         if (stoMainCur > HighLevelForBuy && stoMainNow < HighLevelForBuy)
         {
             ExitAll(LONG, Symbol());       
         }
         
         if (stoMainCur < LowLevelForSell && stoMainNow > LowLevelForSell)
         {              
             ExitAll(SHORT, Symbol());
         }
    }     
    
    checkDrawDown();
    
    if (UseTrailingStop)
    {
        tailingStopOrders();    
    }
}

void tailingStopOrders() 
{            
    for (int i = OrdersTotal() - 1; i >= 0; i--) 
    {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;             
      if(OrderMagicNumber() == MagicNumber)
      {
         string symbolName = OrderSymbol();
         double dDigits = MarketInfo(symbolName, MODE_DIGITS);
         double dPoint = MarketInfo(symbolName, MODE_POINT);   

         double dAsk = MarketInfo(symbolName, MODE_ASK);
         double dBid = MarketInfo(symbolName, MODE_BID);
             
         if (OrderType() == OP_BUY) 
         {       
            double SL = dBid - TrailingStopLoss.Pips*dPoint;            
            if (dBid-OrderOpenPrice()>=TrailingStopActive.Pips*dPoint) 
            {                 
                if (OrderStopLoss() == 0 || SL >= OrderStopLoss() + TrailingStopStep.Pips*dPoint)
                {
                    modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), SL, OrderTakeProfit());
                }
            }
         }

         if (OrderType() == OP_SELL) 
         {                
            SL = dAsk + TrailingStopLoss.Pips*dPoint;
            if (OrderOpenPrice()-dAsk>=TrailingStopActive.Pips*dPoint && (SL <= OrderStopLoss() - TrailingStopStep.Pips*dPoint|| OrderStopLoss() == 0)) 
            {               
                modifyOrderByPrice(OrderTicket(), OrderOpenPrice(), SL, OrderTakeProfit());
            }
         }
      }
   }
}

double getLots(string symbolName, double lotSize)
{
    int lotDigits = MathLog(MarketInfo(symbolName, MODE_LOTSTEP))/MathLog(0.1); 
    if (Risk.Percent.Of.Balance > 0)
    {        
        double lot = AccountBalance()*Risk.Percent.Of.Balance/100/MarketInfo(symbolName, MODE_MARGINREQUIRED);
        return (NormalizeDouble(lot, lotDigits));
    }
    else
    {
        return (NormalizeDouble(lotSize, lotDigits));
    } 
}

void checkDrawDown()
{
    if (AccountEquity()/(AccountBalance() + AccountCredit()) < 1 - MaxDrawdownPercent/100)
    {
        ExitAll(LONG, Symbol());
        ExitAll(SHORT, Symbol());      
        stopEA = true;
    }    
}

//open an order, if failed try again with RETRYCOUNT times
int DoOpenOrder(string symbolName, int dir, double volume, int stop, int take, color clr, string comment = "")  
{
   double sl, tp, entryPrice;

   int ticket = 0;   

   double lots = volume;
   string info;
   
   double dAsk = MarketInfo(symbolName, MODE_ASK);
   double dBid = MarketInfo(symbolName, MODE_BID);
   double dPoint = MarketInfo(symbolName, MODE_POINT);
   double dDigits = MarketInfo(symbolName, MODE_DIGITS);
   
   for (int i=0; i<RETRYCOUNT; i++) {
     for (int j=0; (j<50) && IsTradeContextBusy(); j++)
         Sleep(100);
      RefreshRates();   

      switch(dir)  {
         case LONG:               
               entryPrice = NormalizeDouble(dAsk, dDigits);
               
               if (stop != 0) { sl = entryPrice-(stop*dPoint); }
                else { sl = 0; }
                if (take != 0) { tp = entryPrice +(take*dPoint); }
                else { tp = 0; }
                
                
                info = "Type: " + dir + ", \nentryPrice: " + DoubleToStr(entryPrice, dDigits) 
                   + ", \nLots " + DoubleToStr(lots, 2) + " , \nStop: " + DoubleToStr(sl, dDigits)  
                   + ", \nTP: " + DoubleToStr(tp, dDigits);
                Print(info);
                Comment(info);                
               
                ticket = OrderSend(Symbol(), OP_BUY, lots, entryPrice, Slippage, sl, tp, comment, MagicNumber, 0, clr);
                if (ticket < 0)  
                {
                    ticket = OrderSend(Symbol(), OP_BUY, lots, entryPrice, Slippage, 0, 0, comment, MagicNumber, 0, clr);                    
                }
                if (ticket > 0)  
                {
                     if(OrderSelect(ticket, SELECT_BY_TICKET))
                     {
                         modifyOrderByPrice(ticket, OrderOpenPrice(), sl, tp);
                     }
                }
                
                break;

         case SHORT:
              entryPrice = NormalizeDouble(dBid, dDigits);
              if (stop != 0) { sl = entryPrice+(stop*dPoint); }
                else { sl = 0; }
                if (take != 0) { tp = entryPrice-(take*dPoint); }
                else { tp = 0; }
                
                info = "Type: " + dir + ", \nentryPrice: " + DoubleToStr(entryPrice, dDigits)
                   + ", \nLots " + DoubleToStr(lots, 2) + " , \nStop: " + DoubleToStr(sl, dDigits)  
                   + ", \nTP: " + DoubleToStr(tp, dDigits);
              Print(info);
              Comment(info);
          
                ticket = OrderSend(Symbol(), OP_SELL, lots, entryPrice, Slippage, sl, tp, comment, MagicNumber, 0, clr);     
                if (ticket < 0)  
                {
                    ticket = OrderSend(Symbol(), OP_SELL, lots, entryPrice, Slippage, 0, 0, comment, MagicNumber, 0, clr);                    
                    
                }   
                if (ticket > 0)  
                {
                   if(OrderSelect(ticket, SELECT_BY_TICKET))
                   {
                       modifyOrderByPrice(ticket, OrderOpenPrice(), sl, tp);
                   }
                }                      
                break;
      }
           
      if( ticket > 0 ) { return( ticket ); }
      else {
         Print("DoOpenOrder: error \'"+ErrorDescription(GetLastError())+"\' when opening entry order");
         Sleep(RETRYDELAY);      
      }
      
   }
      
   return( false );
}


//close an order with specifed ticket, if failed try again with RETRYCOUNT times
bool Exit(int ticket, string symbolName, int dir, double volume, color clr)  
{
    int i, j, cmd;
    double prc, sl, tp, lots;
    string cmt;

    bool closed;

    Print("Exit("+dir+","+DoubleToStr(volume,3)+")");

    for (i=0; i<RETRYCOUNT; i++) {
        for (j=0; (j<50) && IsTradeContextBusy(); j++)
            Sleep(100);
        RefreshRates();

        if (dir == OP_BUY) {
            prc = MarketInfo(symbolName, MODE_BID);
        }
        if (dir == OP_SELL) {
            prc = MarketInfo(symbolName, MODE_ASK);
       }
        Print("Exit: prc="+DoubleToStr(prc,MarketInfo(symbolName, MODE_DIGITS)));

        closed = OrderClose(ticket,volume,prc,Slippage,clr);
        if (closed) {
            Print("Trade closed");

            return (true);
        }

        Print("Exit: error \'"+ErrorDescription(GetLastError())+"\' when exiting with "+DoubleToStr(volume,3)+" @"+DoubleToStr(prc,MarketInfo(symbolName, MODE_DIGITS)));
        Sleep(RETRYDELAY);
    }

    Print("Exit: can\'t enter after "+RETRYCOUNT+" retries");
    return (false);
}

int CountOrders(string symbolName) 
{
   orders.BUY = 0;
   orders.SELL = 0;
   orders.BUYLIMIT = 0;
   orders.BUYSTOP = 0;
   orders.SELLLIMIT = 0;
   orders.SELLSTOP = 0;
   
   for( int i = OrdersTotal() - 1; i >= 0; i--) 
   {   
      if (!OrderSelect( i, SELECT_BY_POS)) continue;
      
      if(OrderMagicNumber() == MagicNumber && OrderSymbol() == symbolName) 
      {                       
         if( OrderType() == OP_BUY ) 
         { 
             orders.BUY++; 
         }
         if( OrderType() == OP_SELL ) 
         { 
             orders.SELL++; 
         }
         if( OrderType() == OP_BUYLIMIT ) 
         { 
             orders.BUYLIMIT++; 
         }
         if( OrderType() == OP_BUYSTOP ) 
         { 
             orders.BUYSTOP++; 
         }
         if( OrderType() == OP_SELLLIMIT ) 
         { 
             orders.SELLLIMIT++; 
         }
         if( OrderType() == OP_SELLSTOP ) 
         { 
             orders.SELLSTOP++; 
         }
      }
   }
   
   orders.total = orders.BUY + orders.SELL;
   
   return(orders.total);

}

//close all open positions with the specified LONG or SHORT direction
void ExitAll(int direction, string symbolName) {       

   int i;
   
   CountOrders(symbolName); 
   if( orders.SELL != 0 && direction == SHORT) 
   {      
      while( orders.SELL != 0 ) 
      {
         for(i = OrdersTotal() - 1; i >= 0; i--) 
         {
            if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;       
            if( OrderMagicNumber() == MagicNumber && OrderSymbol() == symbolName ) 
            {              
                if (OrderType() == OP_SELL) { Exit( OrderTicket(), symbolName, OP_SELL, OrderLots(), Red); }
            }
         }          
         CountOrders(symbolName);                 
      }      
      return( true );
   }
   
   if( orders.BUY != 0 && direction == LONG) 
   {  
      while( orders.BUY != 0 ) 
      {
         for(i = OrdersTotal() - 1; i >= 0; i--) 
         {         
            if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
            if( OrderMagicNumber() == MagicNumber && OrderSymbol() == symbolName) {              
                if (OrderType() == OP_BUY) { Exit(OrderTicket(), symbolName, OP_BUY, OrderLots(), Blue); }
            }
         } 
         
         CountOrders(symbolName);       
      }      
      return( true );
   }   
}

//modify an order with specified ticket, if failed try again with RETRYCOUNT times
bool modifyOrderByPrice(int ticket, double price, double stopLoss, double takeProfit)  
{
   bool retVal = true;     
   
   if(!OrderSelect(ticket, SELECT_BY_TICKET)) return (false);
   
   for (int i=0; i<RETRYCOUNT; i++) 
   {
     for (int j=0; (j<50) && IsTradeContextBusy(); j++)
        Sleep(100);
      RefreshRates();                        

       if (MathAbs(OrderStopLoss() - stopLoss) > 0.00001 || MathAbs(OrderTakeProfit() - takeProfit) > 0.00001)
       {              
           retVal = OrderModify(ticket, price, stopLoss, takeProfit, 0);
       }
         
      if(retVal) { return( true ); } 
      else {
         Print("DoModifyOrder: error \'"+ErrorDescription(GetLastError())+"\' when modifying order SL:", stopLoss, " TP:", takeProfit, " OrderOpenPrice:",OrderOpenPrice(), " OrderStopLoss:",OrderStopLoss());
         Sleep(RETRYDELAY);      
      }  
   }      
   return( false );
}

//return error message for each kind of errorCode
string ErrorDescription(int error_code)
{
    string error_string;

    switch( error_code ) {
        case 0:
        case 1:   error_string="no error";                                                  break;
        case 2:   error_string="common error";                                              break;
        case 3:   error_string="invalid trade parameters";                                  break;
        case 4:   error_string="trade server is busy";                                      break;
        case 5:   error_string="old version of the client terminal";                        break;
        case 6:   error_string="no connection with trade server";                           break;
        case 7:   error_string="not enough rights";                                         break;
        case 8:   error_string="too frequent requests";                                     break;
        case 9:   error_string="malfunctional trade operation (never returned error)";      break;
        case 64:  error_string="account disabled";                                          break;
        case 65:  error_string="invalid account";                                           break;
        case 128: error_string="trade timeout";                                             break;
        case 129: error_string="invalid price";                                             break;
        case 130: error_string="invalid stops";                                             break;
        case 131: error_string="invalid trade volume";                                      break;
        case 132: error_string="market is closed";                                          break;
        case 133: error_string="trade is disabled";                                         break;
        case 134: error_string="not enough money";                                          break;
        case 135: error_string="price changed";                                             break;
        case 136: error_string="off quotes";                                                break;
        case 137: error_string="broker is busy (never returned error)";                     break;
        case 138: error_string="requote";                                                   break;
        case 139: error_string="order is locked";                                           break;
        case 140: error_string="long positions only allowed";                               break;
        case 141: error_string="too many requests";                                         break;
        case 145: error_string="modification denied because order too close to market";     break;
        case 146: error_string="trade context is busy";                                     break;
        case 147: error_string="expirations are denied by broker";                          break;
        case 148: error_string="amount of open and pending orders has reached the limit";   break;
        case 149: error_string="hedging is prohibited";                                     break;
        case 150: error_string="prohibited by FIFO rules";                                  break;
        case 4000: error_string="no error (never generated code)";                          break;
        case 4001: error_string="wrong function pointer";                                   break;
        case 4002: error_string="array index is out of range";                              break;
        case 4003: error_string="no memory for function call stack";                        break;
        case 4004: error_string="recursive stack overflow";                                 break;
        case 4005: error_string="not enough stack for parameter";                           break;
        case 4006: error_string="no memory for parameter string";                           break;
        case 4007: error_string="no memory for temp string";                                break;
        case 4008: error_string="not initialized string";                                   break;
        case 4009: error_string="not initialized string in array";                          break;
        case 4010: error_string="no memory for array\' string";                             break;
        case 4011: error_string="too long string";                                          break;
        case 4012: error_string="remainder from zero divide";                               break;
        case 4013: error_string="zero divide";                                              break;
        case 4014: error_string="unknown command";                                          break;
        case 4015: error_string="wrong jump (never generated error)";                       break;
        case 4016: error_string="not initialized array";                                    break;
        case 4017: error_string="dll calls are not allowed";                                break;
        case 4018: error_string="cannot load library";                                      break;
        case 4019: error_string="cannot call function";                                     break;
        case 4020: error_string="expert function calls are not allowed";                    break;
        case 4021: error_string="not enough memory for temp string returned from function"; break;
        case 4022: error_string="system is busy (never generated error)";                   break;
        case 4050: error_string="invalid function parameters count";                        break;
        case 4051: error_string="invalid function parameter value";                         break;
        case 4052: error_string="string function internal error";                           break;
        case 4053: error_string="some array error";                                         break;
        case 4054: error_string="incorrect series array using";                             break;
        case 4055: error_string="custom indicator error";                                   break;
        case 4056: error_string="arrays are incompatible";                                  break;
        case 4057: error_string="global variables processing error";                        break;
        case 4058: error_string="global variable not found";                                break;
        case 4059: error_string="function is not allowed in testing mode";                  break;
        case 4060: error_string="function is not confirmed";                                break;
        case 4061: error_string="send mail error";                                          break;
        case 4062: error_string="string parameter expected";                                break;
        case 4063: error_string="integer parameter expected";                               break;
        case 4064: error_string="double parameter expected";                                break;
        case 4065: error_string="array as parameter expected";                              break;
        case 4066: error_string="requested history data in update state";                   break;
        case 4099: error_string="end of file";                                              break;
        case 4100: error_string="some file error";                                          break;
        case 4101: error_string="wrong file name";                                          break;
        case 4102: error_string="too many opened files";                                    break;
        case 4103: error_string="cannot open file";                                         break;
        case 4104: error_string="incompatible access to a file";                            break;
        case 4105: error_string="no order selected";                                        break;
        case 4106: error_string="unknown symbol";                                           break;
        case 4107: error_string="invalid price parameter for trade function";               break;
        case 4108: error_string="invalid ticket";                                           break;
        case 4109: error_string="trade is not allowed in the expert properties";            break;
        case 4110: error_string="longs are not allowed in the expert properties";           break;
        case 4111: error_string="shorts are not allowed in the expert properties";          break;
        case 4200: error_string="object is already exist";                                  break;
        case 4201: error_string="unknown object property";                                  break;
        case 4202: error_string="object is not exist";                                      break;
        case 4203: error_string="unknown object type";                                      break;
        case 4204: error_string="no object name";                                           break;
        case 4205: error_string="object coordinates error";                                 break;
        case 4206: error_string="no specified subwindow";                                   break;
        default:   error_string="unknown error";
    }

    return(error_string);
}

